//
//  UIAnimator.m
//  Training-Teacher
//
//  Created by dev on 12-10-30.
//
//

#import "BoxfishAnimator.h"
#import "ControlsPrepareAnimationInfo.h"
#import <QuartzCore/QuartzCore.h>
#import "UICreator.h"
#import "Constants.h"

@implementation BoxfishAnimator

+ (void)appearToCenter:(UIView*)view withParentView:(UIView*)parentView duration:(NSTimeInterval)duration
{
    [parentView addSubview:view];
    CGPoint position = CGPointMake(parentView.bounds.size.width/2, parentView.bounds.size.height/2);
    [self appearToPosition:position withView:view duration:duration];
}

+ (void)appearToPosition:(CGPoint)position withView:(UIView*)view duration:(NSTimeInterval)duration
{
    float scale = 100.;
    view.transform = CGAffineTransformScale(view.transform, 1/scale, 1/scale);
    [UIView animateWithDuration:duration animations:^{
        view.transform = CGAffineTransformScale(view.transform, scale, scale);
        view.center = position;
    }];
}

+ (void)disappearToPosition:(CGPoint)position withView:(UIView*)view duration:(NSTimeInterval)duration completion:(void (^)(void))action
{
    float scale = 100.;
    [UIView animateWithDuration:duration animations:^{
        view.center = position;
        view.transform = CGAffineTransformScale(view.transform, 1/scale, 1/scale);
    } completion:^(BOOL finished) {
        [view removeFromSuperview];
        
        if (action) {
            action();
        }
    }];
}

+ (void)moveFromBottom:(UIView*)view
        withParentView:(UIView*)parentView
               offsetX:(float)offsetX
            toPosition:(CGPoint)toPosition
              duration:(NSTimeInterval)duration
{
    view.center = CGPointMake(offsetX + view.bounds.size.width/2, parentView.bounds.size.height + view.bounds.size.height/2);
    [parentView addSubview:view];
    
    [UIView animateWithDuration:duration animations:^{
        view.center = toPosition;
    }];
}


+ (void)moveFromBottom:(UIView*)view withParentView:(UIView*)parentView toPosition:(CGPoint)toPosition duration:(NSTimeInterval)duration
{
    view.center = CGPointMake(parentView.bounds.size.width/2, parentView.bounds.size.height + view.bounds.size.height/2);
    [parentView addSubview:view];
    
    [UIView animateWithDuration:duration animations:^{
        view.center = toPosition;
    }];
}

+ (void)flyInFromHorizontalEdge:(NSArray*)info swipeDirection:(SwipeDirection)direction
{
    float timeSpan = .2f;
    
    if (SwipeRight == direction) {
        for (int i=0; i<info.count; i++) {
            ControlsPrepareAnimationInfo *unitInfo = info[i];
            if ([unitInfo isKindOfClass:[ControlsPrepareAnimationInfo class]]) {
                [BoxfishAnimator flyInFromLeftEdge:unitInfo.view withTargetPosition:unitInfo.targetPostion duration:PageTransitionTime + (i+1)*timeSpan];
            }
        }

    } else {
        for (int i=0; i<info.count; i++) {
            ControlsPrepareAnimationInfo *unitInfo = info[i];
            if ([unitInfo isKindOfClass:[ControlsPrepareAnimationInfo class]]) {
                [BoxfishAnimator flyInFromRightEdge:unitInfo.view withTargetPosition:unitInfo.targetPostion parentView:unitInfo.parentView duration:PageTransitionTime + (i+1)*timeSpan];
            }
        }
    }
    
}

+ (void)flyOutofLeftEdge:(UIView*)view duration:(NSTimeInterval)duration
{
    CGPoint targetPostion = CGPointMake(- view.bounds.size.width / 2, view.center.y);
    
    [UIView animateWithDuration:duration animations:^{
        view.center = targetPostion;
    }];
}

+ (void)flyInFromRightEdge:(UIView*)view
        withTargetPosition:(CGPoint)targetPostion
                parentView:(UIView*)parentView
                  duration:(NSTimeInterval)duration
{
    CGPoint sourcePoint = CGPointMake(parentView.bounds.size.width + view.bounds.size.width/2, targetPostion.y);
    view.center = sourcePoint;
    
    [UIView animateWithDuration:duration animations:^{
        view.center = targetPostion;
    }];
}

+ (void)flyInFromLeftEdge:(UIView*)view
       withTargetPosition:(CGPoint)targetPostion
                 duration:(NSTimeInterval)duration
{
    CGPoint sourcePoint = CGPointMake(- view.bounds.size.width/2, targetPostion.y);
    view.center = sourcePoint;
    
    [UIView animateWithDuration:duration animations:^{
        view.center = targetPostion;
    }];
}

+ (void)jump:(UIView*)view withOffset:(float)offset
{
    [BoxfishAnimator jump:view withOffset:offset jumpTimes:1];
}

+ (void)jump:(UIView*)view withOffset:(float)offset jumpTimes:(int)jumpTimes
{
    [BoxfishAnimator jump:view withOffset:offset jumpTimes:jumpTimes completion:nil];
}

+ (void)jump:(UIView*)view withOffset:(float)offset jumpTimes:(int)jumpTimes completion:(void (^)(void))action
{
    if (jumpTimes < 1) {
        if (action) {
            action();
        }
        return;
    }
    
    CGPoint originalCenter = view.center;
    
    [UIView animateWithDuration:.2 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        view.center = CGPointMake(view.center.x, view.center.y - offset);
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:.2 animations:^{
            view.center = originalCenter;
        } completion:^(BOOL finished) {
            float newOffset = offset/2;
            float newJumpTimes = jumpTimes - 1;
            [self jump:view withOffset:newOffset jumpTimes:newJumpTimes completion:action];
        }];
    }];
}

+ (void)pulse:(UIView*)view
{
    [BoxfishAnimator pulse:view completion:nil];
}

+ (void)pulse:(UIView*)view completion:(void (^)(void))action
{
	// pulse animation thanks to:  http://delackner.com/blog/2009/12/mimicking-uialertviews-animated-transition/
    view.transform = CGAffineTransformMakeScale(0.6, 0.6);
	[UIView animateWithDuration: 0.2
					 animations: ^{
						 view.transform = CGAffineTransformMakeScale(1.1, 1.1);
					 }
					 completion: ^(BOOL finished){
						 [UIView animateWithDuration:1.0/15.0
										  animations: ^{
											  view.transform = CGAffineTransformMakeScale(0.9, 0.9);
										  }
										  completion: ^(BOOL finished){
											  [UIView animateWithDuration:1.0/7.5
															   animations: ^{
																   view.transform = CGAffineTransformIdentity;
															   } completion:^(BOOL finished) {
                                                                   if (action) {
                                                                       action();
                                                                   }
                                                               }];
										  }];
					 }];
	
}

+ (void)verticalFlipFromView:(UIView*)fromView toView:(UIView*)toView withParentView:(UIView*)parentView
{
    [toView removeFromSuperview];
    
    [UIView animateWithDuration:.5f animations:^{
        fromView.layer.transform = CATransform3DMakeRotation(M_PI_2,1.0,0.0,0.0); //flip halfway
    } completion:^(BOOL finished) {
        [fromView removeFromSuperview];
        [parentView addSubview:toView];
        toView.layer.transform = CATransform3DMakeRotation(3 * M_PI_2,1.0,0.0,0.0);
        
        [UIView animateWithDuration:.5f animations:^{
            toView.layer.transform = CATransform3DMakeRotation(0,1.0,0.0,0.0); //flip halfway
        }];
    }];
}

+ (void)blink:(UIView*)view
{
    [self blink:view duration:.5];
}

+ (void)blink:(UIView*)view duration:(CGFloat)duration
{
    CABasicAnimation *pulseAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
    pulseAnimation.duration = duration;
    pulseAnimation.toValue = [NSNumber numberWithFloat:0];
    pulseAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    pulseAnimation.autoreverses = YES;
    pulseAnimation.repeatCount = FLT_MAX;
    [view.layer addAnimation:pulseAnimation forKey:nil];
}

+ (void)beamFromBottom:(UIView*)containerView contentView:(UIView*)contentView duration:(NSTimeInterval)duration targetSize:(CGSize)targetSize completion:(void (^)(void))action
{
    containerView.clipsToBounds = YES;
    
    [containerView addSubview:contentView];
    contentView.center = CGPointMake(containerView.frame.size.width/2, containerView.frame.size.height - contentView.frame.size.height/2);
    
    CGPoint leftBottomPos = CGPointMake(containerView.frame.origin.x, containerView.frame.size.height);
    
    CGPoint newCenter = CGPointMake(containerView.center.x, containerView.center.y - (targetSize.height/2 - containerView.frame.size.height/2));
    
    [UIView animateWithDuration:.7 animations:^{
        containerView.bounds = CGRectMake(0,leftBottomPos.y - targetSize.height,targetSize.width, targetSize.height);
        containerView.center = newCenter;
        
    } completion:^(BOOL finished) {
        if (action) {
            action();
        }
    }];
}

+ (void)shakeHorizontal:(UIView*)view completion:(void (^)(void))action
{
    // Animate the alert to show that the entered string was wrong
    // "Shakes" similar to OS X login screen
    CGAffineTransform moveRight = CGAffineTransformTranslate(CGAffineTransformIdentity, 20, 0);
    CGAffineTransform moveLeft = CGAffineTransformTranslate(CGAffineTransformIdentity, -20, 0);
    CGAffineTransform resetTransform = CGAffineTransformTranslate(CGAffineTransformIdentity, 0, 0);
    
    [UIView animateWithDuration:0.1 animations:^{
        // Translate left
        view.transform = moveLeft;
        
    } completion:^(BOOL finished) {
        
        [UIView animateWithDuration:0.1 animations:^{
            
            // Translate right
            view.transform = moveRight;
            
        } completion:^(BOOL finished) {
            
            [UIView animateWithDuration:0.1 animations:^{
                
                // Translate left
                view.transform = moveLeft;
                
            } completion:^(BOOL finished) {
                
                [UIView animateWithDuration:0.1 animations:^{
                    
                    // Translate to origin
                    view.transform = resetTransform;
                } completion:^(BOOL finished) {
                    if (action) {
                        action();
                    }
                }];
            }];
            
        }];
    }];

}

+ (void)showInfoInScreenCenterWithText:(NSString*)text
                             textColor:(UIColor*)textColor
                                  font:(UIFont*)font
                            completion:(void (^)(void))completion
{
    UILabel *textLabel = [UICreator createLabel:text
                                            color:textColor
                                             font:font]; 
    
    textLabel.shadowColor = [UIColor blackColor];
    textLabel.shadowOffset = CGSizeFromString(@"{2,2}");
    
    [[UIApplication sharedApplication].keyWindow addSubview:textLabel];
    textLabel.center = CGPointMake(textLabel.superview.frame.size.width/2,
                                     textLabel.superview.frame.size.height/2);
    textLabel.transform = CGAffineTransformMakeScale(2.5, 2.5);
    
    [UIView animateWithDuration:.5 animations:^{
        textLabel.transform = CGAffineTransformMakeScale(2.49, 2.49);
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:.5 animations:^{
            textLabel.transform = CGAffineTransformTranslate(textLabel.transform, 0, -50);
            textLabel.alpha = 0;
        } completion:^(BOOL finished) {
            [textLabel removeFromSuperview];
            if (completion) {
                completion();
            }
        }];
    }];
}

+ (void)shakeView:(UIView*)view withAngle:(float)angle duration:(float)duration
{
    [self shakeView:view withAngle:angle duration:duration repeatCount:NSIntegerMax];
}

+ (void)shakeView:(UIView*)view withAngle:(float)angle duration:(float)duration repeatCount:(int)repeatCount
{
    CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    [anim setToValue:@(0.0f)];
    [anim setFromValue:@(angle)]; // rotation angle
    [anim setDuration:0.2];
    [anim setRepeatCount:repeatCount];
    [anim setAutoreverses:YES];
    [view.layer addAnimation:anim forKey:@"iconShake"];
}

+ (void)revealFromLeftByView:(UIView*)view duration:(float)duration
{
    [BoxfishAnimator revealFromLeftByView:view duration:duration isAutoRemove:NO];
}

+ (void)revealFromLeftByView:(UIView*)view duration:(float)duration isAutoRemove:(BOOL)isAutoRemove
{
    view.autoresizesSubviews = NO;
    view.clipsToBounds = YES;
    
    CGRect originalFrame = view.frame;
    view.frame = CGRectMake(originalFrame.origin.x, originalFrame.origin.y, 0, originalFrame.size.height);
    
    [UIView animateWithDuration:duration animations:^{
        view.frame = originalFrame;
    } completion:^(BOOL finished) {
        view.autoresizesSubviews = YES;
        
        if (isAutoRemove) {
            [UIView animateWithDuration:.5 animations:^{
                view.alpha = 0;
            } completion:^(BOOL finished) {
                [view removeFromSuperview];
            }];
        }
    }];
    
}
@end
